(/) describe & visualize single variables (univariate) (-) gather interesting observations for further investigation (-) gather possible new features for extraction
insights
- Seattle: events come in waves within the year (peak in Nov, low in Jul) but stable across years,
- Houston: events seem stable, spontaneous less in Jul and Nov,
- York: stable but jump to more in 2018, stable across week and year
- Los Angeles: kind of stable but spike around 2017 and increase 2019 and 2020, over week spikes on monday and thursday, little wave with peak in Jan and low an Jun, distribution over hours shows significant peak at 15:00
- all: distribution over month days always low at first and last two, distribution over minutes have (different, but all at end of hour) enormous peaks for each city
- since human judgment seems to be involved, the duration has peaks at the full hours, you even can see the dips in the poisson like distribution
- duration stats: Seattle median 60 min, q3 120 min; New York median 47 min q3 72 min; Los Angeles median 60 min q3 120 min, Houston median 60 min q3 98 min; Los Angeles and Seattle seem similar in distribution
(!) compare 4 big cities which are all close to the coast but vary in significantly in longitude and latitude
head(weather)
summary(weather)
EventId Type Severity StartTime EndTime TimeZone LocationLat LocationLng
Length:12226 Cold : 365 Heavy : 439 Min. :2016-01-01 08:47:00 Min. :2016-01-01 09:47:00 US/Central:2900 Min. :29.98 Min. :-122.31
Class :character Fog :2920 Light :6792 1st Qu.:2017-04-08 08:59:45 1st Qu.:2017-04-08 11:06:30 US/Eastern:3656 1st Qu.:34.02 1st Qu.:-122.31
Mode :character Hail : 6 Moderate:3428 Median :2018-09-27 02:42:30 Median :2018-09-27 03:02:30 US/Pacific:5670 Median :40.78 Median : -95.36
Precipitation: 139 Other : 6 Mean :2018-08-09 22:18:52 Mean :2018-08-09 23:49:14 Mean :38.70 Mean :-100.68
Rain :8296 Severe :1422 3rd Qu.:2019-11-24 10:37:30 3rd Qu.:2019-11-24 12:37:30 3rd Qu.:47.44 3rd Qu.: -73.97
Snow : 494 UNK : 139 Max. :2020-12-31 23:22:00 Max. :2020-12-31 23:53:00 Max. :47.44 Max. : -73.97
Storm : 6
City Duration
Houston :2900 Length:12226
Los Angeles:2378 Class :difftime
New York :3656 Mode :numeric
Seattle :3292
StartTime and EndTime look almost the same, thus we only look at StartTime for univariate exploration Seattle: events come in waves within the year (peak in Nov, low in Jul) but stable across years, Houston: events seem stable, spontaneous less in Jul and Nov, New York: stable but jump to more in 2018, stable across week and year Los Angeles: kind of stable but spike around 2017 and increase 2019 and 2020, over week spikes on monday and thursday, little wave with peak in Jan and low an Jun, distribution over hours shows significant peak at 15:00 all: distribution over month days always low at first and last two, distribution over minutes have (different, but all at end of hour) enormous peaks for each city
startTime_plot <- weather %>%
ggplot(aes(x = StartTime, y = City, col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("StartTime of the events")
ggplotly(startTime_plot)
# https://r4ds.had.co.nz/dates-and-times.html
# Note that when you use date-times in a numeric context (like in a histogram), 1 means 1 second, so a binwidth of 86400 means one day. For dates, 1 means 1 day.
startTime_freqplot <- weather %>%
ggplot(aes(x = StartTime, col = City)) +
geom_freqpoly(bins = 30) + # binwidth = 86400 seconds = 1 day, 600 s = 10 minutes
theme_minimal() +
ggtitle("frequency plot for StartTime") +
facet_grid(rows = vars(City))
ggplotly(startTime_freqplot)
startTime_barplot_wday <- weather %>%
mutate(wday = wday(StartTime, label = TRUE)) %>%
ggplot(aes(x = wday, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over week days")
ggplotly(startTime_barplot_wday)
startTime_barplot_year <- weather %>%
mutate(year = year(StartTime)) %>%
ggplot(aes(x = year, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over years")
ggplotly(startTime_barplot_year)
startTime_barplot_month <- weather %>%
mutate(month = month(StartTime, label = TRUE)) %>%
ggplot(aes(x = month, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over months")
ggplotly(startTime_barplot_month)
startTime_barplot_yday <- weather %>%
mutate(yday = yday(StartTime)) %>%
ggplot(aes(x = yday, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over days of year")
ggplotly(startTime_barplot_yday)
startTime_barplot_mday <- weather %>%
mutate(mday = mday(StartTime)) %>%
ggplot(aes(x = mday, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over days of month")
ggplotly(startTime_barplot_mday)
startTime_barplot_hour <- weather %>%
mutate(hour = hour(StartTime)) %>%
ggplot(aes(x = hour, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over hours")
ggplotly(startTime_barplot_hour)
startTime_barplot_minute <- weather %>%
mutate(minute = minute(StartTime)) %>%
ggplot(aes(x = minute, fill = City)) +
geom_bar() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("distribution over minutes")
ggplotly(startTime_barplot_minute)
# Setting larger components of a date to a constant is a powerful technique that allows you to explore patterns in the smaller components.
startTime_count <- weather %>%
mutate(start_hour = update(StartTime, mday = 1)) %>%
ggplot(aes(x = start_hour, col = City)) +
geom_freqpoly() +
facet_grid(rows = vars(City)) +
theme_minimal() +
ggtitle("not seeing the use here, but wanted to check out")
ggplotly(startTime_count)
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
since human judgment seems to be involved, the duration has peaks at the full hours, you even can see the dips in the poisson like distribution duration stats: Seattle median 60 min, q3 120 min; New York median 47 min q3 72 min; Los Angeles median 60 min q3 120 min, Houston median 60 min q3 98 min; Los Angeles and Seattle seem similar in distribution
duration_histplot_all <- weather %>%
ggplot(aes(x = Duration, fill = fct_infreq(City))) +
geom_histogram(binwidth = 1) +
theme_minimal() +
ggtitle("Duration of the events")
ggplotly(duration_histplot_all)
Don't know how to automatically pick scale for object of type difftime. Defaulting to continuous.
duration_histplot <- weather %>%
ggplot(aes(x = Duration, fill = fct_infreq(City))) +
geom_histogram(binwidth = 30) +
theme_minimal() +
ggtitle("Duration of the events") +
facet_grid(rows = vars(City))
ggplotly(duration_histplot)
Don't know how to automatically pick scale for object of type difftime. Defaulting to continuous.
duration_boxplot <- weather %>%
ggplot(aes(y = as.numeric(Duration), x = City, col = fct_infreq(City))) +
geom_boxplot() +
theme_minimal() +
coord_flip() +
ggtitle("Duration of the events")
ggplotly(duration_boxplot)
duration_boxplot <- weather %>%
ggplot(aes(x = as.numeric(Duration), y = City, col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("Duration of the events")
ggplotly(duration_boxplot)
library(dlookr)
weather %>%
mutate(Duration = as.numeric(Duration)) %>%
plot_normality(Duration)

LS0tDQp0aXRsZTogImRlc2NyaWJlIGFuZCB2aXN1YWxpemUgb2YgVVMgd2VhdGhlciBldmVudCBkYXRhIg0Kc3VidGl0bGU6ICJjaXR5IHNlbGVjdGlvbiAtIHVuaXZhcmlhdGUgZm9yIHRpbWUgdmFyaWFibGVzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KLS0tDQpwdXJwb3NlIG9mIG5vdGVib29rDQotLS0NCg0KICAoLykgZGVzY3JpYmUgJiB2aXN1YWxpemUgc2luZ2xlIHZhcmlhYmxlcyAodW5pdmFyaWF0ZSkNCiAgKC0pIGdhdGhlciBpbnRlcmVzdGluZyBvYnNlcnZhdGlvbnMgZm9yIGZ1cnRoZXIgaW52ZXN0aWdhdGlvbg0KICAoLSkgZ2F0aGVyIHBvc3NpYmxlIG5ldyBmZWF0dXJlcyBmb3IgZXh0cmFjdGlvbg0KICANCnRvZG9zOg0KICAoLSkgLi4uDQoNCi0tLQ0KaW5mb3JtYXRpb24NCi0tLQ0KaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9zb2JoYW5tb29zYXZpL3VzLXdlYXRoZXItZXZlbnRzDQpodHRwczovL3Ntb29zYXZpLm9yZy9kYXRhc2V0cy9sc3R3DQoNCk1vb3NhdmksIFNvYmhhbiwgTW9oYW1tYWQgSG9zc2VpbiBTYW1hdmF0aWFuLCBBcm5hYiBOYW5kaSwgU3Jpbml2YXNhbiBQYXJ0aGFzYXJhdGh5LCBhbmQgUmFqaXYgUmFtbmF0aC4g4oCcU2hvcnQgYW5kIExvbmctdGVybSBQYXR0ZXJuIERpc2NvdmVyeSBPdmVyIExhcmdlLVNjYWxlIEdlby1TcGF0aW90ZW1wb3JhbCBEYXRhLuKAnSBJbiBQcm9jZWVkaW5ncyBvZiB0aGUgMjV0aCBBQ00gU0lHS0REIEludGVybmF0aW9uYWwgQ29uZmVyZW5jZSBvbiBLbm93bGVkZ2UgRGlzY292ZXJ5ICYgRGF0YSBNaW5pbmcsIEFDTSwgMjAxOS4NCg0KV2VhdGhlciBldmVudCBpcyBhIHNwYXRpb3RlbXBvcmFsIGVudGl0eSwgd2hlcmUgc3VjaCBhbiBlbnRpdHkgaXMgYXNzb2NpYXRlZCB3aXRoIGxvY2F0aW9uIGFuZCB0aW1lLiBGb2xsb3dpbmcgaXMgdGhlIGRlc2NyaXB0aW9uIG9mIGF2YWlsYWJsZSB3ZWF0aGVyIGV2ZW50IHR5cGVzOg0KDQogICAgU2V2ZXJlLUNvbGQ6IFRoZSBjYXNlIG9mIGhhdmluZyBleHRyZW1lbHkgbG93IHRlbXBlcmF0dXJlLCB3aXRoIHRlbXBlcmF0dXJlIGJlbG93IC0yMy43IGRlZ3JlZXMgb2YgQ2Vsc2l1cy4NCiAgICBGb2c6IFRoZSBjYXNlIHdoZXJlIHRoZXJlIGlzIGxvdyB2aXNpYmlsaXR5IGNvbmRpdGlvbiBhcyBhIHJlc3VsdCBvZiBmb2cgb3IgaGF6ZS4NCiAgICBIYWlsOiBUaGUgY2FzZSBvZiBoYXZpbmcgc29saWQgcHJlY2lwaXRhdGlvbiBpbmNsdWRpbmcgaWNlIHBlbGxldHMgYW5kIGhhaWwuDQogICAgUmFpbjogVGhlIGNhc2Ugb2YgaGF2aW5nIHJhaW4sIHJhbmdpbmcgZnJvbSBsaWdodCB0byBoZWF2eS4NCiAgICBTbm93OiBUaGUgY2FzZSBvZiBoYXZpbmcgc25vdywgcmFuZ2luZyBmcm9tIGxpZ2h0IHRvIGhlYXZ5Lg0KICAgIFN0b3JtOiBUaGUgZXh0cmVtZWx5IHdpbmR5IGNvbmRpdGlvbiwgd2hlcmUgdGhlIHdpbmQgc3BlZWQgaXMgYXQgbGVhc3QgNjAga20vaC4NCiAgICBPdGhlciBQcmVjaXBpdGF0aW9uOiBBbnkgb3RoZXIgdHlwZSBvZiBwcmVjaXBpdGF0aW9uIHdoaWNoIGNhbm5vdCBiZSBhc3NpZ25lZCB0byBwcmV2aW91c2x5IGRlc2NyaWJlZCBldmVudCB0eXBlcy4NCg0KVGhlIHdlYXRoZXIgZGF0YSBpcyBwcm92aWRlZCBpbiB0ZXJtcyBvZiBhIENTViBmaWxlIHdpdGggdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOg0KICAgICAgQXR0cmlidXRlCSAgICAgICAgRGVzY3JpcHRpb24JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVsbGFibGUNCjEJICAgIEV2ZW50SWQJICAgICAgICAgIFRoaXMgaXMgdGhlIGlkZW50aWZpZXIgb2YgYSByZWNvcmQJICAgICAgICAgICAgICAgICAgICAgICAgTm8NCjIgICAJVHlwZQkgICAgICAgICAgICBUaGUgdHlwZSBvZiBhbiBldmVudDsgZXhhbXBsZXMgYXJlIHJhaW4gYW5kIHNub3cuCSAgICAgICAgICBObw0KMwkgICAgU2V2ZXJpdHkJICAgICAgICBUaGUgc2V2ZXJpdHkgb2YgYW4gZXZlbnQsIHdoZXJldmVyIGFwcGxpY2FibGUuICAgICAgICAJICAgIFllcw0KNAkgICAgU3RhcnRUaW1lIChVVEMpCSAgVGhlIHN0YXJ0IHRpbWUgb2YgYW4gZXZlbnQgaW4gVVRDIHRpbWUgem9uZS4gICAgICAgICAgCSAgICBObw0KNQkgICAgRW5kVGltZSAoVVRDKQkgICAgVGhlIGVuZCB0aW1lIG9mIGFuIGV2ZW50IGluIFVUQyB0aW1lIHpvbmUuCSAgICAgICAgICAgICAgICBObw0KNgkgICAgVGltZVpvbmUJICAgICAgICBUaGUgVVMtYmFzZWQgdGltZXpvbmUgYmFzZWQgb24gdGhlIGxvY2F0aW9uIG9mIGFuIGV2ZW50ICAgICBObw0KICAgICAgICAgICAgICAgICAgICAgICAgKGVhc3Rlcm4sIGNlbnRyYWwsIG1vdW50YWluLCBhbmQgcGFjaWZpYykuCQ0KNwkgICAgTG9jYXRpb25MYXQJICAgICAgVGhlIGxhdGl0dWRlIGluIEdQUyBjb29yZGluYXRlLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQo4ICAgCUxvY2F0aW9uTG5nCSAgICAgIFRoZSBsb25naXR1ZGUgaW4gR1BTIGNvb3JkaW5hdGUuCSAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQo5CSAgICBBaXJwb3J0Q29kZQkgICAgICBUaGUgYWlycG9ydCBzdGF0aW9uIHRoYXQgYSB3ZWF0aGVyIGV2ZW50IGlzIHJlcG9ydGVkIGZyb20uCVllcw0KMTAJICBDaXR5CSAgICAgICAgICAgIFRoZSBjaXR5IGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTEJICBDb3VudHkJICAgICAgICAgIFRoZSBjb3VudHkgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTIJICBTdGF0ZQkgICAgICAgICAgICBUaGUgc3RhdGUgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTMJICBaaXBDb2RlCSAgICAgICAgICBUaGUgemlwY29kZSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KDQotLS0NCmluc2lnaHRzIA0KLS0tDQogIA0KICAoaSkgU2VhdHRsZTogZXZlbnRzIGNvbWUgaW4gd2F2ZXMgd2l0aGluIHRoZSB5ZWFyIChwZWFrIGluIE5vdiwgbG93IGluIEp1bCkgYnV0IHN0YWJsZSBhY3Jvc3MgeWVhcnMsIA0KICAoaSkgSG91c3RvbjogZXZlbnRzIHNlZW0gc3RhYmxlLCBzcG9udGFuZW91cyBsZXNzIGluIEp1bCBhbmQgTm92LCANCiAgKGkpIFlvcms6IHN0YWJsZSBidXQganVtcCB0byBtb3JlIGluIDIwMTgsIHN0YWJsZSBhY3Jvc3Mgd2VlayBhbmQgeWVhcg0KICAoaSkgTG9zIEFuZ2VsZXM6IGtpbmQgb2Ygc3RhYmxlIGJ1dCBzcGlrZSBhcm91bmQgMjAxNyBhbmQgaW5jcmVhc2UgMjAxOSBhbmQgMjAyMCwgb3ZlciB3ZWVrIHNwaWtlcyBvbiBtb25kYXkgYW5kIHRodXJzZGF5LCBsaXR0bGUgd2F2ZSB3aXRoIHBlYWsgaW4gSmFuIGFuZCBsb3cgYW4gSnVuLCANCiAgICAgIGRpc3RyaWJ1dGlvbiBvdmVyIGhvdXJzIHNob3dzIHNpZ25pZmljYW50IHBlYWsgYXQgMTU6MDANCiAgKGkpIGFsbDogZGlzdHJpYnV0aW9uIG92ZXIgbW9udGggZGF5cyBhbHdheXMgbG93IGF0IGZpcnN0IGFuZCBsYXN0IHR3bywgZGlzdHJpYnV0aW9uIG92ZXIgbWludXRlcyBoYXZlIChkaWZmZXJlbnQsIGJ1dCBhbGwgYXQgZW5kIG9mIGhvdXIpIGVub3Jtb3VzIHBlYWtzIGZvciBlYWNoIGNpdHkNCiAgKGkpIHNpbmNlIGh1bWFuIGp1ZGdtZW50IHNlZW1zIHRvIGJlIGludm9sdmVkLCB0aGUgZHVyYXRpb24gaGFzIHBlYWtzIGF0IHRoZSBmdWxsIGhvdXJzLCB5b3UgZXZlbiBjYW4gc2VlIHRoZSBkaXBzIGluIHRoZSBwb2lzc29uIGxpa2UgZGlzdHJpYnV0aW9uDQogIChpKSBkdXJhdGlvbiBzdGF0czogU2VhdHRsZSBtZWRpYW4gNjAgbWluLCBxMyAxMjAgbWluOyBOZXcgWW9yayBtZWRpYW4gNDcgbWluIHEzIDcyIG1pbjsgTG9zIEFuZ2VsZXMgbWVkaWFuIDYwIG1pbiBxMyAxMjAgbWluLCBIb3VzdG9uIG1lZGlhbiA2MCBtaW4gcTMgOTggbWluOyANCiAgICAgIExvcyBBbmdlbGVzIGFuZCBTZWF0dGxlIHNlZW0gc2ltaWxhciBpbiBkaXN0cmlidXRpb24NCg0KLS0tDQpzdG9yaWVzDQotLS0NCg0KICAoISkgY29tcGFyZSA0IGJpZyBjaXRpZXMgd2hpY2ggYXJlIGFsbCBjbG9zZSB0byB0aGUgY29hc3QgYnV0IHZhcnkgaW4gc2lnbmlmaWNhbnRseSBpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlDQoNCi0tLQ0KbG9hZCBwYWNrYWdlcw0KLS0tDQpgYGB7ciBsb2FkIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgdGlkeSBkYXRhIGZyYW1lDQpsaWJyYXJ5KGdndGhlbWVzKSAjIGZvciBleHRyYSBwbG90IHRoZW1lcw0KbGlicmFyeShwbG90bHkpICMgbWFrZSBnZ3Bsb3RzIGludGVyYWN0aXZlDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgIyBmdW5jdGlvbnMgdG8gd29yayB3aXRoIGRhdGUtdGltZXMgYW5kIHRpbWUtc3BhbnMNCmxpYnJhcnkoY29ycnBsb3QpICMgY29ycmVsYXRpb24gcGxvdHMNCmBgYA0KDQotLS0NCm92ZXJ2aWV3DQotLS0NCmBgYHtyfQ0KaGVhZCh3ZWF0aGVyKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkod2VhdGhlcikNCmBgYA0KDQotLS0NCnVuaXZhcmlhdGUgU3RhcnRUaW1lDQotLS0NClN0YXJ0VGltZSBhbmQgRW5kVGltZSBsb29rIGFsbW9zdCB0aGUgc2FtZSwgdGh1cyB3ZSBvbmx5IGxvb2sgYXQgU3RhcnRUaW1lIGZvciB1bml2YXJpYXRlIGV4cGxvcmF0aW9uDQpTZWF0dGxlOiBldmVudHMgY29tZSBpbiB3YXZlcyB3aXRoaW4gdGhlIHllYXIgKHBlYWsgaW4gTm92LCBsb3cgaW4gSnVsKSBidXQgc3RhYmxlIGFjcm9zcyB5ZWFycywgDQpIb3VzdG9uOiBldmVudHMgc2VlbSBzdGFibGUsIHNwb250YW5lb3VzIGxlc3MgaW4gSnVsIGFuZCBOb3YsIA0KTmV3IFlvcms6IHN0YWJsZSBidXQganVtcCB0byBtb3JlIGluIDIwMTgsIHN0YWJsZSBhY3Jvc3Mgd2VlayBhbmQgeWVhcg0KTG9zIEFuZ2VsZXM6IGtpbmQgb2Ygc3RhYmxlIGJ1dCBzcGlrZSBhcm91bmQgMjAxNyBhbmQgaW5jcmVhc2UgMjAxOSBhbmQgMjAyMCwgb3ZlciB3ZWVrIHNwaWtlcyBvbiBtb25kYXkgYW5kIHRodXJzZGF5LCBsaXR0bGUgd2F2ZSB3aXRoIHBlYWsgaW4gSmFuIGFuZCBsb3cgYW4gSnVuLCBkaXN0cmlidXRpb24gb3ZlciBob3VycyBzaG93cyBzaWduaWZpY2FudCBwZWFrIGF0IDE1OjAwDQphbGw6IGRpc3RyaWJ1dGlvbiBvdmVyIG1vbnRoIGRheXMgYWx3YXlzIGxvdyBhdCBmaXJzdCBhbmQgbGFzdCB0d28sIGRpc3RyaWJ1dGlvbiBvdmVyIG1pbnV0ZXMgaGF2ZSAoZGlmZmVyZW50LCBidXQgYWxsIGF0IGVuZCBvZiBob3VyKSBlbm9ybW91cyBwZWFrcyBmb3IgZWFjaCBjaXR5DQoNCmBgYHtyfQ0Kc3RhcnRUaW1lX3Bsb3QgPC0gd2VhdGhlciAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gU3RhcnRUaW1lLCB5ID0gQ2l0eSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiU3RhcnRUaW1lIG9mIHRoZSBldmVudHMiKQ0KDQpnZ3Bsb3RseShzdGFydFRpbWVfcGxvdCkNCmBgYA0KYGBge3J9DQojIGh0dHBzOi8vcjRkcy5oYWQuY28ubnovZGF0ZXMtYW5kLXRpbWVzLmh0bWwNCiMgTm90ZSB0aGF0IHdoZW4geW91IHVzZSBkYXRlLXRpbWVzIGluIGEgbnVtZXJpYyBjb250ZXh0IChsaWtlIGluIGEgaGlzdG9ncmFtKSwgMSBtZWFucyAxIHNlY29uZCwgc28gYSBiaW53aWR0aCBvZiA4NjQwMCBtZWFucyBvbmUgZGF5LiBGb3IgZGF0ZXMsIDEgbWVhbnMgMSBkYXkuDQpzdGFydFRpbWVfZnJlcXBsb3QgPC0gd2VhdGhlciAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gU3RhcnRUaW1lLCBjb2wgPSBDaXR5KSkgKw0KICAgIGdlb21fZnJlcXBvbHkoYmlucyA9IDMwKSArICMgYmlud2lkdGggPSA4NjQwMCBzZWNvbmRzID0gMSBkYXksIDYwMCBzID0gMTAgbWludXRlcw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiZnJlcXVlbmN5IHBsb3QgZm9yIFN0YXJ0VGltZSIpICsNCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENpdHkpKQ0KDQpnZ3Bsb3RseShzdGFydFRpbWVfZnJlcXBsb3QpDQpgYGANCmBgYHtyfQ0Kc3RhcnRUaW1lX2JhcnBsb3Rfd2RheSA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUod2RheSA9IHdkYXkoU3RhcnRUaW1lLCBsYWJlbCA9IFRSVUUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gd2RheSwgZmlsbCA9IENpdHkpKSArDQogICAgZ2VvbV9iYXIoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG92ZXIgd2VlayBkYXlzIikNCiAgDQpnZ3Bsb3RseShzdGFydFRpbWVfYmFycGxvdF93ZGF5KQ0KYGBgDQpgYGB7cn0NCnN0YXJ0VGltZV9iYXJwbG90X3llYXIgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKHllYXIgPSB5ZWFyKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCBmaWxsID0gQ2l0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJkaXN0cmlidXRpb24gb3ZlciB5ZWFycyIpDQogIA0KZ2dwbG90bHkoc3RhcnRUaW1lX2JhcnBsb3RfeWVhcikNCmBgYA0KYGBge3J9DQpzdGFydFRpbWVfYmFycGxvdF9tb250aCA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUobW9udGggPSBtb250aChTdGFydFRpbWUsIGxhYmVsID0gVFJVRSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgZmlsbCA9IENpdHkpKSArDQogICAgZ2VvbV9iYXIoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG92ZXIgbW9udGhzIikNCiAgDQpnZ3Bsb3RseShzdGFydFRpbWVfYmFycGxvdF9tb250aCkNCmBgYA0KYGBge3J9DQpzdGFydFRpbWVfYmFycGxvdF95ZGF5IDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZSh5ZGF5ID0geWRheShTdGFydFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWRheSwgZmlsbCA9IENpdHkpKSArDQogICAgZ2VvbV9iYXIoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG92ZXIgZGF5cyBvZiB5ZWFyIikNCiAgDQpnZ3Bsb3RseShzdGFydFRpbWVfYmFycGxvdF95ZGF5KQ0KYGBgDQpgYGB7cn0NCnN0YXJ0VGltZV9iYXJwbG90X21kYXkgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKG1kYXkgPSBtZGF5KFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZGF5LCBmaWxsID0gQ2l0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJkaXN0cmlidXRpb24gb3ZlciBkYXlzIG9mIG1vbnRoIikNCiAgDQpnZ3Bsb3RseShzdGFydFRpbWVfYmFycGxvdF9tZGF5KQ0KYGBgDQpgYGB7cn0NCnN0YXJ0VGltZV9iYXJwbG90X2hvdXIgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKGhvdXIgPSBob3VyKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBob3VyLCBmaWxsID0gQ2l0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJkaXN0cmlidXRpb24gb3ZlciBob3VycyIpDQogIA0KZ2dwbG90bHkoc3RhcnRUaW1lX2JhcnBsb3RfaG91cikNCmBgYA0KYGBge3J9DQpzdGFydFRpbWVfYmFycGxvdF9taW51dGUgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKG1pbnV0ZSA9IG1pbnV0ZShTdGFydFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWludXRlLCBmaWxsID0gQ2l0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJkaXN0cmlidXRpb24gb3ZlciBtaW51dGVzIikNCiAgDQpnZ3Bsb3RseShzdGFydFRpbWVfYmFycGxvdF9taW51dGUpDQpgYGANCmBgYHtyfQ0KIyBTZXR0aW5nIGxhcmdlciBjb21wb25lbnRzIG9mIGEgZGF0ZSB0byBhIGNvbnN0YW50IGlzIGEgcG93ZXJmdWwgdGVjaG5pcXVlIHRoYXQgYWxsb3dzIHlvdSB0byBleHBsb3JlIHBhdHRlcm5zIGluIHRoZSBzbWFsbGVyIGNvbXBvbmVudHMuDQpzdGFydFRpbWVfY291bnQgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKHN0YXJ0X2hvdXIgPSB1cGRhdGUoU3RhcnRUaW1lLCBtZGF5ID0gMSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGFydF9ob3VyLCBjb2wgPSBDaXR5KSkgKw0KICAgIGdlb21fZnJlcXBvbHkoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgibm90IHNlZWluZyB0aGUgdXNlIGhlcmUsIGJ1dCB3YW50ZWQgdG8gY2hlY2sgb3V0IikNCg0KZ2dwbG90bHkoc3RhcnRUaW1lX2NvdW50KQ0KYGBgDQoNCi0tLQ0KdW5pdmFyaWF0ZSBEdXJhdGlvbg0KLS0tDQpzaW5jZSBodW1hbiBqdWRnbWVudCBzZWVtcyB0byBiZSBpbnZvbHZlZCwgdGhlIGR1cmF0aW9uIGhhcyBwZWFrcyBhdCB0aGUgZnVsbCBob3VycywgeW91IGV2ZW4gY2FuIHNlZSB0aGUgZGlwcyBpbiB0aGUgcG9pc3NvbiBsaWtlIGRpc3RyaWJ1dGlvbg0KZHVyYXRpb24gc3RhdHM6IFNlYXR0bGUgbWVkaWFuIDYwIG1pbiwgcTMgMTIwIG1pbjsgTmV3IFlvcmsgbWVkaWFuIDQ3IG1pbiBxMyA3MiBtaW47IExvcyBBbmdlbGVzIG1lZGlhbiA2MCBtaW4gcTMgMTIwIG1pbiwgSG91c3RvbiBtZWRpYW4gNjAgbWluIHEzIDk4IG1pbjsgTG9zIEFuZ2VsZXMgYW5kIFNlYXR0bGUgc2VlbSBzaW1pbGFyIGluIGRpc3RyaWJ1dGlvbg0KDQpgYGB7cn0NCmR1cmF0aW9uX2hpc3RwbG90X2FsbCA8LSB3ZWF0aGVyICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBEdXJhdGlvbiwgZmlsbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvZiB0aGUgZXZlbnRzIikNCg0KZ2dwbG90bHkoZHVyYXRpb25faGlzdHBsb3RfYWxsKQ0KYGBgDQpgYGB7cn0NCmR1cmF0aW9uX2hpc3RwbG90IDwtIHdlYXRoZXIgJT4lDQogIGdncGxvdChhZXMoeCA9IER1cmF0aW9uLCBmaWxsID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDMwKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvZiB0aGUgZXZlbnRzIikgKw0KICAgIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoQ2l0eSkpDQoNCmdncGxvdGx5KGR1cmF0aW9uX2hpc3RwbG90KQ0KYGBgDQpgYGB7cn0NCmR1cmF0aW9uX2JveHBsb3QgPC0gd2VhdGhlciAlPiUNCiAgZ2dwbG90KGFlcyh5ID0gYXMubnVtZXJpYyhEdXJhdGlvbiksIHggPSBDaXR5LCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21fYm94cGxvdCgpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgZ2d0aXRsZSgiRHVyYXRpb24gb2YgdGhlIGV2ZW50cyIpDQoNCmdncGxvdGx5KGR1cmF0aW9uX2JveHBsb3QpDQpgYGANCg0KYGBge3J9DQpkdXJhdGlvbl9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBhcy5udW1lcmljKER1cmF0aW9uKSwgeSA9IENpdHksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIkR1cmF0aW9uIG9mIHRoZSBldmVudHMiKQ0KDQpnZ3Bsb3RseShkdXJhdGlvbl9wb2ludCkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZGxvb2tyKQ0KDQp3ZWF0aGVyICU+JSANCiAgbXV0YXRlKER1cmF0aW9uID0gYXMubnVtZXJpYyhEdXJhdGlvbikpICU+JQ0KICBwbG90X25vcm1hbGl0eShEdXJhdGlvbikNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=